home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Graphic Elements 3 / GEQTHack / GEBalls.c < prev    next >
Text File  |  1995-06-13  |  4KB  |  192 lines

  1. /*
  2.     GEBalls.c
  3.     
  4.     Balls for GEQTHack
  5.     
  6.     6/10/95
  7.     
  8.     Al Evans
  9.     
  10. */
  11.  
  12. #include "Rects.h"
  13. #include "GEBalls.h"
  14. #include "GESound.h"
  15.  
  16. short RangedRdm(short min, short max)
  17. {
  18.     short rdm;
  19.     
  20.     rdm = Random();
  21.     if (rdm < 0) 
  22.         rdm = -rdm;
  23.     rdm = rdm % (max - min);
  24.     rdm += min;
  25.     return rdm;
  26. }
  27.  
  28.  
  29. void InitABall(GEWorldPtr world, GrafElPtr aBall)
  30. {
  31.     // Target positions in pre-scaled world coordinates
  32.     short xPos = RangedRdm(ScaleToWorld(world, 4), 
  33.             RectWidth(&world->animationRect) - 
  34.             RectWidth(&aBall->animationRect) - ScaleToWorld(world, 4));
  35.     short yPos = RangedRdm(ScaleToWorld(world, 16), 
  36.             RectHeight(&world->animationRect) - 
  37.             RectHeight(&aBall->animationRect) - ScaleToWorld(world,16));
  38.  
  39.  
  40.     // Set Initial Position in absolute world coordinates
  41.     PtrMoveElementTo(world, aBall, xPos, yPos, false);
  42.     
  43.     // Autochange proc    
  44.     SetAutoChange(world, aBall->objectID, DoBallRandom, nil, 33);
  45.     
  46.     // Movement speed kept in changeData
  47.     aBall->changeData = (Ptr) ((long)  RangedRdm(1, 8) << 16) + 
  48.                     RangedRdm(1, 8);
  49.     
  50.     // Collision proc
  51.     SetCollision(world,  aBall->objectID, DoBallCollide, aBall->drawPlane);
  52. }
  53.  
  54. Boolean InitBallGraphics(GEWorldPtr world)
  55. {
  56.     GrafElPtr    aBall;
  57.     short        ballCount;
  58.     
  59.     for (ballCount = 0; ballCount < numberOfBalls; ballCount++) {
  60.         // Make blue ball
  61.         aBall =  NewAnimatedGraphic(world, firstBBID + ballCount, 
  62.                                         blueBallPlane, rBlueBall, transparent, 0, 0, 2);
  63.         if (aBall == nil) return false;
  64.         InitABall(world, aBall);
  65.         // Make red ball
  66.         aBall =  NewAnimatedGraphic(world, firstRBID + ballCount, 
  67.                                         redBallPlane, rRedBall, transparent, 0, 0, 2);
  68.         if (aBall == nil) return false;
  69.         InitABall(world, aBall);
  70.     }
  71.     GEHoldSound((GESoundPtr) world->userData, rBallSnd, true);
  72.     return true;
  73. }
  74.  
  75.  
  76. GEDirection CheckLimits(Rect *objRect, Rect *limitRect)
  77. {
  78.     if (objRect->right >= limitRect->right)
  79.         return right;
  80.     if (objRect->left <= limitRect->left)
  81.         return left;
  82.     if (objRect->top <= limitRect->top)
  83.         return up;
  84.     if (objRect->bottom >= limitRect->bottom)
  85.         return down;
  86.     return none;
  87. }
  88.  
  89.  
  90. void BounceObj(GEDirection direction, short *xMove, short *yMove)
  91. {
  92.     switch (direction) {
  93.         case right:
  94.             if (*xMove > 0);
  95.                 *xMove = -*xMove;
  96.             break;
  97.         case left:
  98.             if (*xMove < 0);
  99.                 *xMove = -*xMove;
  100.             break;
  101.         case up:
  102.             if (*yMove < 0)
  103.                 *yMove = -*yMove;
  104.             break;
  105.         case down:
  106.             if (*yMove > 0)
  107.                 *yMove = -*yMove;
  108.             break;
  109.     }
  110. }
  111.  
  112. pascal void DoBallRandom(GEWorldPtr world, GrafElPtr obj)
  113. {
  114.     GEDirection collisionDir;
  115.     register short *currXMove = (short *) &obj->changeData + 1;
  116.     register short *currYMove = (short *) &obj->changeData;
  117.     
  118.     collisionDir = CheckLimits(&obj->animationRect, &world->animationRect);
  119.     if (collisionDir != none)
  120.         BounceObj(collisionDir, currXMove, currYMove);
  121.     PtrMoveElement(world, obj, *currXMove, *currYMove);
  122.     
  123. }
  124.  
  125. pascal void DoBallCollide(GEWorldPtr world, GrafElPtr ball, GEDirection dir, CollisionPhase phase, GrafElPtr objHit)
  126. {
  127.     register short *currXMove = (short *) &ball->changeData + 1;
  128.     register short *currYMove = (short *) &ball->changeData;
  129.     
  130.     if (objHit->objectID != 'LOGO') {  // Don't bounce off logo
  131.         
  132.         switch (phase) {
  133.         
  134.             case collisionBegin:
  135.                 SetFrame(world, ball->objectID, 2);
  136.                 GEScheduleSound((GESoundPtr) world->userData, rBallSnd, 1, 0);
  137.             break;
  138.             
  139.             case collisionContinue:
  140.             switch (dir) {
  141.                 case left:
  142.                     if (*currXMove < 0)
  143.                         *currXMove = -*currXMove;
  144.                     break;
  145.                 case right:
  146.                     if (*currXMove > 0)
  147.                         *currXMove = -*currXMove;
  148.                     break;
  149.                 case up:
  150.                     if (*currYMove < 0)
  151.                         *currYMove = -*currYMove;
  152.                     break;
  153.                 case down:
  154.                     if (*currYMove > 0)
  155.                         *currYMove = -*currYMove;
  156.                     break;
  157.                 case upLeft:
  158.                     if (*currYMove < 0)
  159.                         *currYMove = -*currYMove;
  160.                     if (*currXMove < 0)
  161.                         *currXMove = -*currXMove;
  162.                     break;
  163.                 case upRight:
  164.                     if (*currYMove < 0)
  165.                         *currYMove = -*currYMove;
  166.                     if (*currXMove > 0)
  167.                         *currXMove = -*currXMove;
  168.                     break;
  169.                 case downLeft:
  170.                     if (*currYMove > 0)
  171.                         *currYMove = -*currYMove;
  172.                     if (*currXMove < 0)
  173.                         *currXMove = -*currXMove;
  174.                     break;
  175.                 
  176.                 case downRight:
  177.                     if (*currYMove > 0)
  178.                         *currYMove = -*currYMove;
  179.                     if (*currXMove > 0)
  180.                         *currXMove = -*currXMove;
  181.                     break;
  182.             }
  183.             break;
  184.             
  185.         case collisionEnd:
  186.             SetFrame(world, ball->objectID, 1);
  187.             break;
  188.         }
  189.     
  190.     }    
  191. }
  192.